package news.utils.util;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.log4j.Logger;
  
  
//import org.apache.log4j.Logger;  
  
/** 
 *  
 * @author liuhang 
 * 
 */  
public class LoggerUtils {  
  
    static class LoggerWapper {  
  
        private Logger logger;  
  
        private StackTraceElement stackTraceElement;  
  
        private String methodName;  
  
        private int lineNum;  
  
        private Object message;  
  
        private Object wapperMessage;  
  
        private Class<?> clazz;  
  
        public Logger getLogger() {  
            return logger;  
        }  
  
        public void setLogger(Logger logger) {  
            this.logger = logger;  
        }  
  
        public StackTraceElement getStackTraceElement() {  
            return stackTraceElement;  
        }  
  
        public void setStackTraceElement(StackTraceElement stackTraceElement) {  
            this.stackTraceElement = stackTraceElement;  
        }  
  
        public String getMethodName() {  
            return methodName;  
        }  
  
        public void setMethodName(String methodName) {  
            this.methodName = methodName;  
        }  
  
        public int getLineNum() {  
            return lineNum;  
        }  
  
        public void setLineNum(int lineNum) {  
            this.lineNum = lineNum;  
        }  
  
        public Object getMessage() {  
            return message;  
        }  
  
        public void setMessage(Object message) {  
            this.message = message;  
        }  
  
        public Object getWapperMessage() {  
            return wapperMessage;  
        }  
  
        public void setWapperMessage(Object wapperMessage) {  
            this.wapperMessage = wapperMessage;  
        }  
  
        public Class<?> getClazz() {  
            return clazz;  
        }  
  
        public void setClazz(Class<?> clazz) {  
            this.clazz = clazz;  
        }  
  
        public LoggerWapper(Object message) {  
            super();  
            this.message = message;  
        }  
  
        @Override  
        public String toString() {  
            return "LoggerWapper [logger=" + logger + ", stackTraceElement=" + stackTraceElement + ", methodName="  
                    + methodName + ", lineNum=" + lineNum + ", message=" + message + ", wapperMessage=" + wapperMessage  
                    + ", clazz=" + clazz + "]";  
        }  
          
    }  
  
    private static Class<?> getInvokeClass(StackTraceElement stackTraceElement) {  
        if (stackTraceElement != null) {  
            Class<?> clazz;  
            try {  
                clazz = Class.forName(stackTraceElement.getClassName());  
                return clazz;  
            } catch (ClassNotFoundException e) {  
                e.printStackTrace();  
            }  
        }  
        return null;  
    }  
  
    private static String getInvokeMethodName(StackTraceElement stackTraceElement) {  
        if (stackTraceElement != null) {  
            String methodName = null;  
            methodName = stackTraceElement.getMethodName();  
            return methodName;  
        }  
        return null;  
    }  
  
    private static Object msgWapper(Object message, StackTraceElement stackTraceElement) {  
        if (stackTraceElement != null) {  
            StringBuffer stringBuffer = new StringBuffer("");  
            int lineNum = getInvokeLineNum(stackTraceElement);  
            String methodName = getInvokeMethodName(stackTraceElement);  
            Class<?> clazz = getInvokeClass(stackTraceElement);  
            if (lineNum > 0) {  
                stringBuffer.append(  
                        clazz.getName() + "." + methodName + "(" + clazz.getSimpleName() + ".java:" + lineNum + ")");  
                stringBuffer.append(" -  " + message);  
            }  
            return stringBuffer.toString();  
        }  
        return message;  
    }  
  
    private static int getInvokeLineNum(StackTraceElement stackTraceElement) {  
        int num = 0;  
        if (stackTraceElement != null) {  
            num = stackTraceElement.getLineNumber();  
        }  
        return num;  
    }  
  
    private static StackTraceElement getInvokeInfo(int num) {  
        if (num > -1) {  
            Lock lock = new ReentrantLock();  
            lock.lock();  
            StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();  
            lock.unlock();  
            if (stackTraceElements != null && stackTraceElements.length > num) {  
                StackTraceElement stackTraceElement = stackTraceElements[num];  
                return stackTraceElement;  
            }  
        }  
        return null;  
    }  
  
    private static LoggerWapper getLoggerWapper(Object message) {  
        LoggerWapper loggerWapper = new LoggerWapper(message);  
        StackTraceElement stackTraceElement = getInvokeInfo(4);  
        loggerWapper.setStackTraceElement(stackTraceElement);  
        Class<?> clazz = getInvokeClass(stackTraceElement);  
        loggerWapper.setClazz(clazz);  
        Logger logger = Logger.getLogger(clazz);  
        loggerWapper.setLogger(logger);  
        String methodName = getInvokeMethodName(stackTraceElement);  
        loggerWapper.setMethodName(methodName);  
        int lineNum = getInvokeLineNum(stackTraceElement);  
        loggerWapper.setLineNum(lineNum);  
        Object wapperMessage = msgWapper(message, loggerWapper.getStackTraceElement());  
        loggerWapper.setWapperMessage(wapperMessage);;  
        return loggerWapper;  
    }  
  
    public static void debug(Object message) {  
        LoggerWapper loggerWapper = getLoggerWapper(message);  
        loggerWapper.getLogger().debug(loggerWapper.getWapperMessage());  
    }  
  
    public static void debug(Object message, Throwable t) {  
        LoggerWapper loggerWapper = getLoggerWapper(message);  
        loggerWapper.getLogger().debug(loggerWapper.getWapperMessage(), t);  
    }  
  
    public static void error(Object message) {  
        LoggerWapper loggerWapper = getLoggerWapper(message);  
        loggerWapper.getLogger().error(loggerWapper.getWapperMessage());  
    }  
  
    public static void error(Object message, Throwable t) {  
        LoggerWapper loggerWapper = getLoggerWapper(message);  
        loggerWapper.getLogger().error(loggerWapper.getWapperMessage(), t);  
    }  
  
    public static void fatal(Object message) {  
        LoggerWapper loggerWapper = getLoggerWapper(message);  
        loggerWapper.getLogger().fatal(loggerWapper.getWapperMessage());  
    }  
  
    public static void fatal(Object message, Throwable t) {  
        LoggerWapper loggerWapper = getLoggerWapper(message);  
        loggerWapper.getLogger().fatal(loggerWapper.getWapperMessage(), t);  
    }  
  
    public static void info(Object message) {  
        LoggerWapper loggerWapper = getLoggerWapper(message);  
        loggerWapper.getLogger().info(loggerWapper.getWapperMessage());  
    }  
  
    public static void info(Object message, Throwable t) {  
        LoggerWapper loggerWapper = getLoggerWapper(message);  
        loggerWapper.getLogger().info(loggerWapper.getWapperMessage(), t);  
    }  
  
    public static void warn(Object message) {  
        LoggerWapper loggerWapper = getLoggerWapper(message);  
        loggerWapper.getLogger().warn(loggerWapper.getWapperMessage());  
    }  
  
    public static void warn(Object message, Throwable t) {  
        LoggerWapper loggerWapper = getLoggerWapper(message);  
        loggerWapper.getLogger().warn(loggerWapper.getWapperMessage(), t);  
    }  
  
}  